module func_vec_mod; 
use vec_mod;
implicit none;
logical, save :: FUNC_VEC_MOD_TRACE_NEW = .TRUE.;
logical, save :: FUNC_VEC_MOD_TRACE_IF = .TRUE.;
logical, save :: FUNC_VEC_MOD_TRACE_ENTRY = .FALSE.;
!logical, save :: VEC_MOD_TRACE_ENTRY = .TRUE.;
integer, save :: NEW_FUNC_COUNT = 0;

type FUNC_VEC_T
  real(R14), pointer :: x(:), y(:), drv(:), drv2(:); 
end type
type FUNC_VEC_PT  !PT - pointer to type; or type-pointer
  type(FUNC_VEC_T), pointer :: fp; ! no better way 
end type


contains 


function new_func2(xp, yp) result(res);  
  implicit none;  
  type(FUNC_VEC_T), pointer :: res;!!! no, do not use FUNC_VEC_PT      
  real(R14), pointer :: xp(:), yp(:);
  integer :: status;
  call dbg_info("-->new_func(xp,yp)", FUNC_VEC_MOD_TRACE_ENTRY);
  allocate(res, STAT=status);
  res%x => xp;
  res%y => yp;
  NULLIFY(res%drv, res%drv2)
  NEW_FUNC_COUNT = NEW_FUNC_COUNT + 1;
  call dbg_int("NEW_FUNC_COUNT=", NEW_FUNC_COUNT, FUNC_VEC_MOD_TRACE_NEW);
  return;
end function
  
  
function new_func(xp) result(res);  
  implicit none;  
  type(FUNC_VEC_T), pointer :: res;!!! no, do not use FUNC_VEC_PT      
  real(R14), pointer :: xp(:);
  integer :: status;
  call dbg_info("-->new_func()", FUNC_VEC_MOD_TRACE_ENTRY);
  allocate(res, STAT=status);
  res%x => xp;
  res%y = new_vec_from(xp);
  NULLIFY(res%drv, res%drv2)
  NEW_FUNC_COUNT = NEW_FUNC_COUNT + 1;
  call dbg_int("NEW_FUNC_COUNT=", NEW_FUNC_COUNT, FUNC_VEC_MOD_TRACE_NEW);
  return;
end function


subroutine del_func(res);  implicit none;  
  type(FUNC_VEC_T), pointer :: res      
  call dbg_info("-->del_func()", FUNC_VEC_MOD_TRACE_ENTRY);
  call dbg_bool("ASSOCIATED(res)=", ASSOCIATED(res), FUNC_VEC_MOD_TRACE_IF);  
  if (ASSOCIATED(res)) then
    call del_vec(res%x);
  end if 
  call del_func_y(res);     
  return;
end subroutine

! keep x
subroutine del_func_y(res);  implicit none;  
  type(FUNC_VEC_T), pointer :: res      
  call dbg_info("-->del_func_y()", FUNC_VEC_MOD_TRACE_ENTRY);
  call dbg_bool("ASSOCIATED(res)=", ASSOCIATED(res), FUNC_VEC_MOD_TRACE_IF);
  if (ASSOCIATED(res)) then
    call del_vec(res%y);
    call del_vec(res%drv);
    call del_vec(res%drv2);
    DEALLOCATE(res);
    NEW_FUNC_COUNT = NEW_FUNC_COUNT - 1;
  end if     
  return;
end subroutine

! note 'y'; meaning only y-values are freed
subroutine set_func_py(oldp, newp);  implicit none;  
  type(FUNC_VEC_T), pointer :: oldp, newp;      
  call dbg_info("-->set_func_py()", FUNC_VEC_MOD_TRACE_ENTRY);
  call dbg_bool("ASSOCIATED(oldp)=", ASSOCIATED(oldp), FUNC_VEC_MOD_TRACE_IF);
  call dbg_bool("ASSOCIATED(newp)=", ASSOCIATED(newp), FUNC_VEC_MOD_TRACE_IF);
  call del_func_y(oldp);  
  oldp => newp;
  return;
end subroutine

end module 